/**
React 组件的生命周期分为几个主要阶段，通常可以分为以下几个阶段：
1. 挂载（Mounting）：
   - constructor：构造函数，在组件被创建时调用，通常用于初始化状态和绑定方法。
   - static getDerivedStateFromProps：在组件接收到新的 props 时调用，可以根据新的 props 更新 state。
   - render：返回要渲染的 JSX。
   - componentDidMount：组件挂载后调用，适合进行网络请求或添加订阅等操作。

2. 更新（Updating）：
   - static getDerivedStateFromProps：当组件接收到新的 props 或者 state 更新时调用。
   - shouldComponentUpdate：可以控制组件是否重新渲染，返回 true 或 false。
   - render：重新渲染组件。
   - getSnapshotBeforeUpdate：在更新前获取快照，返回值会作为 componentDidUpdate 的第三个参数。
   - componentDidUpdate：组件更新后调用，适合进行 DOM 操作或网络请求。

3. 卸载（Unmounting）：
   - componentWillUnmount：组件卸载前调用，适合清理定时器、取消网络请求等。

4. 错误处理（Error Handling）：
   - static getDerivedStateFromError：当子组件抛出错误时调用，可以更新 state 以显示备用 UI。
   - componentDidCatch：捕获子组件的错误，可以用于日志记录等。

这些生命周期方法使得开发者可以在组件的不同阶段执行特定的操作，从而更好地控制组件的行为。随着 React 16.3 及以上版本的发布，推荐使用 Hooks 进行状态管理和副作用处理，Hooks 提供了更简洁的方式来管理组件的生命周期。 
 */
import React, { Component } from "react";

export default class LifeCycle extends Component {
  // 1. constructor构造方法: 初始化数据
  constructor(props) {
    super(props);
    console.log("holle constructor");

    super();
    this.state = {
      message: "hello lift cycle",
      derivedValue: props.initialValue,
    };
  }

  changeText() {
    this.setState({
      message: "hello world",
    });
  }

  // 2. render渲染方法: 渲染组件
  render() {
    console.log("render start");
    const { message } = this.state;

    return (
      <div>
        <h2>{message}</h2>
        <p>{message}是程序员的第一个代码!</p>
        <button onClick={(e) => this.changeText()}>修改文本</button>
      </div>
    );
  }

  // 3. 组件被渲染到DOM: 被挂载到DOM上
  componentDidMount() {
    console.log("componentDidMount");
  }

  // 4. 组件的DOM被更新完成: DOM发生更新
  // prevProps: 上一次的props
  // prevState: 上一次的state
  // snapshot: 快照
  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("componentDidUpdate", prevProps, prevState, snapshot);
  }

  // 5. 组件从DOM中卸载: 从DOM中移除, 组件被卸载
  componentWillUnmount() {
    console.log("componentWillUnmount");
  }

  // getSnapshotBeforeUpdate: 在组件更新之前, DOM更新之前
  getSnapshotBeforeUpdate() {
    console.log("getSnapshotBeforeUpdate");
    return {
      scrollPosition: window.scrollY,
    };
  }

  // 不常用的生命周期函数, shouldComponentUpdate: 是否需要更新组件
  shouldComponentUpdate() {
    console.log("shouldComponentUpdate");
    return true;
  }

  // 不常用的生命周期函数, static getDerivedStateFromProps: 从props中获取派生状态
  static getDerivedStateFromProps(nextProps, prevState) {
    // 如果新的 props 与当前 state 不同，则更新 state
    if (nextProps.initialValue !== prevState.derivedValue) {
      return {
        derivedValue: nextProps.initialValue,
      };
    }
    // 返回 null 表示不需要更新 state
    return null;
  }
}
